package com.mm.scheme.service;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mm.common.config.RedisProperties;
import com.mm.common.domain.po.Result;
import com.mm.common.enums.ResultCode;
import com.mm.common.utils.cacheUtil.CacheClient;
import com.mm.common.utils.DataUtils;
import com.mm.common.utils.SessionHolder;
import com.mm.scheme.config.TemplateProperties;
import com.mm.scheme.domian.po.Template;
import com.mm.scheme.mapper.TemplateMapper;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @BelongsProject: chatgpt-java-develop
 * @BelongsPackage: com.unfbx.service
 * @Author : 游在海里的鱼
 * @CreateTime : 2024-03-20  20:16
 * @Version : 1.0
 * @ClassName : TODO
 * @Description : TODO
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TemplateServiceImpl extends ServiceImpl<TemplateMapper, Template> implements ITemplateService {
    private final CacheClient cacheClient;
    private final TemplateProperties templateProperties;
    private final RedisProperties redisProperties;

    /** ---------------------------------------------------------------------------------------------------------------------
     * @Method  : 新增模板
    **/
    public Result addTemplate(){
        int count = lambdaQuery().eq(Template::getUid, SessionHolder.getUser()).count();
        if(count >= templateProperties.template_capacity){
            return Result.failed(ResultCode.FAILED_OVER_CAPACITY);
        }
        
        //新建模板
        Template template = lambdaQuery()
                .eq(Template::getTitle,templateProperties.default_title)
                .eq(Template::getUid, SessionHolder.getUser()).one();
        if(template != null){
            return Result.failed(ResultCode.FAILED_TITLE_DUPLICATIO);
        }
        //初始化模板
        template = new Template();
        template.setUid(SessionHolder.getUser());
        template.setTitle(templateProperties.default_title);
        initialize(template);
        //保存模板
        if(!save(template)){
            return Result.failed(ResultCode.FAILED);
        }
        //获取模板在数据库里的模板
        Template cur = lambdaQuery().eq(Template::getTitle,templateProperties.default_title).eq(Template::getUid, SessionHolder.getUser()).one();
        if(cur == null){
            return Result.failed(ResultCode.FAILED);
        }
        //清空缓存
        String key = redisProperties.cache_template_list_pre + SessionHolder.getUser();
        cacheClient.removeCache(key);
        //返回模板
        return Result.success(cur);
    }

    /** ---------------------------------------------------------------------------------------------------------------------
     * @Method  : 编辑模板
     * @Describe: TODO
     * @modifier: [public] [实例方法]
     **/
    public Result editTemplate(Template template){
        //参数检验
        if(template == null
                || DataUtils.isNaturalNumInvalid(template.getId())
                || StrUtil.isBlank(template.getTitle())){
            return Result.failed(ResultCode.FAILED_PARAMS_VALIDATE);
        }

        //根据Id获取模板
        Template cur = getById(template.getId());
        if(cur == null){
            return Result.failed(ResultCode.FAILED);
        }

        //判断标题是否重复
        Template cur2 = lambdaQuery().eq(Template::getTitle,template.getTitle())
                               .eq(Template::getUid, SessionHolder.getUser())
                               .one();
        if(cur2 != null && cur2.getId() != cur.getId()){
            return Result.failed(ResultCode.FAILED_TITLE_DUPLICATIO);
        }

        //修改并保存
        cur.setAll(template);
        cur.setUpdateTime(new Date());

        if(!saveOrUpdate(template)){
            log.error("[addTemplate] [模板:"+template.getTitle()+"]修改失败");
            return Result.failed(ResultCode.FAILED);
        }

        //清缓存
        String key = redisProperties.cache_template_list_pre + SessionHolder.getUser();
        cacheClient.removeCache(key);
        //成功
        return Result.success();
    }

    /** ---------------------------------------------------------------------------------------------------------------------
     * @Method  : 删除模板
     * @Describe: TODO
     * @modifier: [public] [实例方法]
     **/
    public Result deleteTemplate(Long id){
        //1. 参数检验
        if(DataUtils.isNaturalNumInvalid(id)){
            return Result.failed(ResultCode.FAILED_PARAMS_VALIDATE);
        }
        //检验uid是否匹配
        Template template = getById(id);
        if(template == null){
            log.error("[deleteTemplate] [ID:" +id+"]的模板不存在");
            return Result.failed(ResultCode.FAILED);
        }
        //删除模板
        if(!removeById(id)){
            return Result.failed(ResultCode.FAILED);
        }
        //清空模板缓存
        String key = redisProperties.cache_template_list_pre + SessionHolder.getUser();
        cacheClient.removeCache(key);
        //成功
        return Result.success();
    }

    /** ---------------------------------------------------------------------------------------------------------------------
     * @Method  : 获取此用户的所有方案
     * @Describe: TODO
     * @modifier: [public] [实例方法]
     **/
    public Result getAllTemplate(){

        //获取方案列表
        List<Template> templateList = cacheClient.queryListPassThrough(redisProperties.cache_template_list_pre, SessionHolder.getUser(), Template.class
                , redisProperties.cache_template_time, TimeUnit.MINUTES,this::selectTemplateAll);

        if(templateList == null){
            log.error("[getAllTemplate] [用户："+ SessionHolder.getUser()+"]获取所有方案失败");
            return Result.failed(ResultCode.FAILED);
        }
        log.info("[getAllTemplate] [用户："+ SessionHolder.getUser()+"]获取所有成功");
        return Result.success(templateList);
    }

    /** ---------------------------------------------------------------------------------------------------------------------
     * @Method  : 查询所有模板
    **/
    public List<Template> selectTemplateAll(Long uid){
        return lambdaQuery().eq(Template::getUid,uid).orderByDesc(Template::getUpdateTime).list();
    }

    /* ---------------------------------------------------------------------------------------------------------------------
     * @Method  : 初始化方案
     * @Describe: TODO
     * @modifier: [private] [实例方法]
     **/
    private boolean initialize(Template template){
        if(template.getTitle() == null){
            template.setTitle(templateProperties.default_title);
        }
        if(template.getContent() == null ){
            template.setContent(templateProperties.default_content);
        }
        if(template.getCreateTime() == null){
            template.setCreateTime(new Date());
        }
        if(template.getUpdateTime() == null){
            template.setUpdateTime(new Date());
        }
        return true;
    }
}
